package poker.plans.croupier;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import poker.beliefs.*;
import jadex.adapter.fipa.*;
import jadex.runtime.*;

public class ControlHandPlan extends Plan {
	
	private Table t;
	private Pack p;
	AgentIdentifier[] players;
	List<AgentIdentifier> gamers;
	
	public void body() {
		System.out.println("CROUPIER: Let's begin playing this hand");
		//Get necessary beliefs
		t = (Table) getBeliefbase().getBelief("table").getFact();
		p = (Pack) getBeliefbase().getBelief("pack").getFact();
		//Initialize pot to 0
		getBeliefbase().getBelief("acpot").setFact(new Integer(0));
		players = t.getPlayers();
		gamers = (List) getBeliefbase().getBelief("gamers").getFact();
		AgentIdentifier aID;
		int totalpot;
		
		while(t.getNumRound() != Table.WINNER_CHECK) {
			IGoal goal = createGoal("getbets");
			dispatchSubgoalAndWait(goal);
			
			gamers = (List) getBeliefbase().getBelief("gamers").getFact();
			totalpot = ((Integer)getBeliefbase().getBelief("acpot").getFact()).intValue();
			//Detect if the game is over --> just check gamers size <= 1
			if (gamers.size() == 0) {
				System.out.println("El croupier exige un aumento de sueldo\nLos jugadores son gilipollas");
				return;
			}
			else if (gamers.size() == 1) { //we have a winner!
				aID = gamers.get(0);
				
				// Ask the winner to show his hand (this is not done in the real world)
				IMessageEvent showHand = createMessageEvent("showHand");
				showHand.getParameterSet(SFipa.RECEIVERS).addValue(aID);
				System.out.println("CROUPIER: Asking winner "+aID.getName()+" his hand");
				IMessageEvent answer = sendMessageAndWait(showHand);
				
				// Tell the winner that he has won
				IMessageEvent msg = createMessageEvent("youWin");
				msg.setContent(new Integer(totalpot));
				msg.getParameterSet(SFipa.RECEIVERS).addValue(aID);
				sendMessage(msg);
				
				//Add the winner and the hand to GameResult
				GameResult grs = new GameResult();
				Vector<AgentIdentifier> winners = new Vector<AgentIdentifier>();
				winners.add(aID);
				grs.setWinners(winners);
				grs.setWinnerHand((Hand) answer.getContent());
				
				// Now we have to tell the others the result of the game
				IGoal notifyResult = createGoal("notify_result");
		        notifyResult.getParameter("game_result").setValue(grs);
		        dispatchSubgoalAndWait(notifyResult);
				
				//Send the message
				/*msg.setContent(grs);
				msg.getParameterSet(SFipa.RECEIVERS).addValues(players);
				sendMessage(msg);*/
				
				//Update statistics
				//TODO: Define what stadistics
		        /*
		        IGoal deal = createGoal("deal_cards");
		        dispatchTopLevelGoal(deal);
		        */
				return;
			}
			
			//Create Communitycards
			if (t.getNumRound() != Table.RIVER) {
				System.out.println("ROUND "+t.getNumRound());
				genCommunityCards();
				getBeliefbase().getBelief("pack").setFact(p);
			}
			t.nextRound();
			getBeliefbase().getBelief("table").setFact(t);
		}
	}
	
	private void genCommunityCards() {
		//Generate Community cards
		System.out.println("CROUPIER: Setting the community cards");
		
		Card[] commcards;
		if (t.getNumRound() == Table.PREFLOP) commcards = new Card[3];
		else commcards = new Card[1];
		
		for (int i = 0; i < commcards.length; i++) {
			commcards[i] = p.dealCard();
			System.out.println("CROUPIER: Card "+i+": "+commcards[i].toString());
		}
		t.setCommCards(commcards);
		IMessageEvent msg = createMessageEvent("deal_card");
		DealCard dc = new DealCard();
		dc.setCards(commcards);
		msg.setContent(dc);
		Iterator it = gamers.iterator();
		AgentIdentifier id;
		while (it.hasNext()) {
			id = (AgentIdentifier) it.next();
			msg.getParameterSet(SFipa.RECEIVERS).addValue(id);
		}
		sendMessage(msg);
	}

}
